package com.lyn.file;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

/**
 * 文件工具类
 *
 * @author Lyn 2022/12/8
 * @version 1.0.0
 */
public class FileUtil {
    /**
     * 创建文件夹
     *
     * @param path 路径
     * @return 文件夹路径
     */
    public static String createFolder(String path) {
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        return file.getAbsolutePath();
    }

    /**
     * 创建文件
     *
     * @param path 路径
     * @return 文件夹路径
     */
    public static String createFile(String path) throws IOException {
        File file = new File(path);
        if (!file.exists()) {
            file.createNewFile();
        }
        return file.getAbsolutePath();
    }

    /**
     * 删除文件
     *
     * @param path 文件路径
     * @return true成功 false失败
     */
    public static boolean deleteFile(String path) {
        File file = new File(path);
        if (file.exists()) {
            if (file.isFile()) {
                return file.delete();
            }
        }
        return false;
    }

    /**
     * 删除文件夹
     *
     * @param path 文件夹路径
     */
    public static void deleteFolder(String path) {
        File file = new File(path);
        if (file.exists()) {
            File[] files = file.listFiles();
            assert files != null;
            for (File itemFile : files) {
                if (itemFile.isFile()) {
                    itemFile.delete();
                } else {
                    deleteFolder(itemFile.getAbsolutePath());
                }
            }
        }
    }

    /**
     * 拷贝文件到指定目录下
     *
     * @param file       文件
     * @param folderPath 文件夹路径
     * @return 文件夹下的文件路径
     * @throws IOException io异常
     */
    public static String copyFileToFolder(File file, String folderPath) {
        return copyFileToFolder(file, folderPath, null);
    }

    /**
     * 拷贝文件到指定目录下
     *
     * @param file       文件
     * @param folderPath 文件夹路径
     * @return 文件夹下的文件路径
     * @throws IOException io异常
     */
    public static String copyFileToFolder(File file, String folderPath, ProgressListener listener) {
        try {
            FileInputStream in = new FileInputStream(file);
            return copyFileToFolder(in, file.getName(), folderPath, file.length(), listener);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据输入流在指定目录下创建文件
     *
     * @param in            输入流
     * @param fileName      文件名称
     * @param folderPath    文件夹路径
     * @param contentLength 文件长度
     * @param listener      进度监听器
     * @return 文件路径
     * @throws IOException io异常
     */
    public static String copyFileToFolder(InputStream in, String fileName, String folderPath, long contentLength, ProgressListener listener) {
        try {
            File newFile = new File(folderPath, fileName);
            if (!newFile.exists()) {
                newFile.createNewFile();
            }
            FileOutputStream out = new FileOutputStream(newFile);
            inputStreamToOutPutStream(in, out, contentLength, listener);
            return newFile.getAbsolutePath();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 写入文件流
     *
     * @param in       输入流
     * @param out      输出流
     * @param listener 进度监听器
     */
    public static void inputStreamToOutPutStream(InputStream in, OutputStream out, long contentLength, ProgressListener listener) {
        try {
            if (listener != null) {
                listener.onStart();
            }
            int len;
            byte[] buff = new byte[1024];
            long sum = 0;
            while ((len = in.read(buff)) > 0) {
                out.write(buff, 0, len);
                sum += len;
                int progress = (int) (sum * 1.0f / contentLength * 100);
                if (listener != null) {
                    listener.onProgress(progress);
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            try {
                out.flush();
                out.close();
                in.close();
            } catch (Throwable e) {
                e.printStackTrace();
            }
            if (listener != null) {
                listener.onEnd();
            }
        }
    }

    /**
     * 保存txt文件
     * @param text 文本
     * @param path 路径
     * @param fileName 文件名
     * @param append 追加
     * @return 路径
     */
    public static String saveTxt(String text, String path, String fileName,boolean append) {
        try {
            File folderFile = new File(path);
            if (!folderFile.exists()){
                folderFile.mkdirs();
            }
            File file = new File(path, fileName);
            if (!file.exists()){
                file.createNewFile();
            }
            FileOutputStream fileOutputStream = new FileOutputStream(file,append);
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream));
            bufferedWriter.write(text);
            bufferedWriter.flush();
            bufferedWriter.close();
            return file.getAbsolutePath();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 读取txt文本
     * @param path 路径
     * @return 文本内容
     */
    public static String readTxt(String path){
        try {
            File file = new File(path);
            FileInputStream fileInputStream = new FileInputStream(file);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine())!=null){
                sb.append(line).append("\n");
            }
            bufferedReader.close();
            return sb.toString();
        }catch (Throwable e){
            e.printStackTrace();
        }
        return null;
    }
}
